#!/usr/bin/env python

### imports
import sys,os,unittest,getopt
from numpy import array,sum
sys.path.append("..")
sys.path.append(os.path.join(".","data"))
sys.path.append(os.path.join("..","SpectralMix"))
from SpectralMix import SpectralCluster
from SpectralCluster import SpectralCluster
from SimulationData import dataScatter, dataScatterLabels
from SimulationData import dataLetters, dataLettersLabels
from SimulationData import dataCircle, dataCircleLabels
from SimulationData import dataNetwork1, dataNetwork1Labels

try:
    import pygraphviz as pgv
except:
    print "WARNING: PyGraphviz is not installed?"

### parse inputs 
VERBOSE = False
optlist, args = getopt.getopt(sys.argv[1:], 'v')
for o, a in optlist:
    if o == '-v':
        VERBOSE = True

## class that tests four simulated data sets 
class SpectralClusterTest(unittest.TestCase):

    ## scatter plot example
    def testAllData(self):
        sc = SpectralCluster(dataScatter,k=2,labels=dataScatterLabels,projID='scatter',makePlots=True,fileType='png',verbose=VERBOSE)
        self.assertEqual(sc.evaluation['precision'],1.0)
        self.assertEqual(sc.evaluation['recall'],1.0)
        sc.make_plot('scatter',data=dataScatter,labels=sc.clustResults['labels'],name='scatter')

        #sc.make_plot('graph',labels=sc.labels,weighted=False,name='original')
        #plt = sc.make_plot('eigenSpace',labels=sc.inferenceResults['labels'])    


        ## test circle data
        sc = SpectralCluster(dataCircle,k=2,labels=dataCircleLabels,projID='circle',makePlots=True,fileType='png',verbose=VERBOSE)
        self.assertEqual(sc.evaluation['precision'],1.0)
        self.assertEqual(sc.evaluation['recall'],1.0)
        sc.make_plot('scatter',data=dataCircle,labels=sc.clustResults['labels'],name='circle')
        
        ## test letters data example
        sc = SpectralCluster(dataLetters,k=3,labels=dataLettersLabels,projID='letters',makePlots=True,fileType='png',sigma=5,verbose=VERBOSE)
        self.assertEqual(sc.evaluation['precision'],1.0)
        self.assertEqual(sc.evaluation['recall'],1.0)
        sc.make_plot('scatter',data=dataLetters,labels=sc.clustResults['labels'],name='letters')

        ## test network data example 
        dn1 = dataNetwork1
        dn1Labels = dataNetwork1Labels
        sc = SpectralCluster(dn1,k=2,dataHeader=dn1.nodes(),labels=dn1Labels,projID='network1',dtype='graph',makePlots=True,fileType='png',verbose=VERBOSE)
        self.assertEqual(sc.evaluation['precision'],1.0)
        self.assertEqual(sc.evaluation['recall'],1.0)        
        sc.make_plot('graph',labels=sc.clustResults['labels'],name='network1')

        ## compiles the data from the four tested sets for visualization (requires imagemagick)
        #figTypes = ['','original','method']
        #figNames = ['scatter','circle','letters','network1']
        fig1 = 'scatter_scatter.png'
        fig2 = 'circle_scatter.png'
        fig3 = 'letters_scatter.png'
        fig4 = 'graph_network1.png'
        figs = [fig1,fig2,fig3,fig4]
        out =  'composite.miff'

        os.system("montage -bordercolor white -background white -geometry +4+4 -tile 2x2 -font arial -frame 3 %s %s %s %s %s "%(fig1,fig2,fig3,fig4,out))
        os.system("convert composite.miff composite.png")
    
        ## remove the figures
        for fig in figs:
            os.remove(fig)

        os.remove(out)
        print "\tTo visually inspect the results -- see composite.png"

### Run the tests 
if __name__ == '__main__':
    unittest.main()
